package com.xiaodeng.xdblogspringboot.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiaodeng.xdblogspringboot.mapper.CommentsMapper;
import com.xiaodeng.xdblogspringboot.mapper.UserMapper;
import com.xiaodeng.xdblogspringboot.pojo.Comments;
import com.xiaodeng.xdblogspringboot.pojo.DTO.CommentCreateDTO;
import com.xiaodeng.xdblogspringboot.pojo.DTO.CommentDTO;
import com.xiaodeng.xdblogspringboot.pojo.Likes;
import com.xiaodeng.xdblogspringboot.pojo.User;
import com.xiaodeng.xdblogspringboot.pojo.VO.CommentVO;
import com.xiaodeng.xdblogspringboot.pojo.VO.LikesVO;
import com.xiaodeng.xdblogspringboot.service.CommentsService;
import io.micrometer.common.util.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentsServiceImpl implements CommentsService {
    @Autowired
    private CommentsMapper commentsMapper;

    @Autowired
    private UserMapper userMapper;
    /**
     * 按类型更新点赞量
     */
    @Override

    public void updateLike(CommentDTO dto) {
        if (dto.getCommentId() != null) {
            handleCommentLike(dto.getCommentId(), dto.getUpdateStatus(), dto.getUserId()); // 新增userId参数
        } else {
            handleArticleLike(dto.getArticleId(), dto.getUpdateStatus(), dto.getUserId()); // 新增userId参数
        }
    }

    /**
     * 处理评论点赞（增/减）
     */
    private void handleCommentLike(Long commentId, Short updateStatus, Long userId) {
        // 检查评论存在性
        if (commentsMapper.existsComment(commentId) == null) {
            throw new RuntimeException("评论不存在: " + commentId);
        }

        // 处理点赞表逻辑
        handleLike(commentId, userId, (short) 2, updateStatus); // likeType=2 表示评论点赞
    }

    /**
     * 处理文章点赞统计（增/减）
     */
    private void handleArticleLike(Long articleId, Short updateStatus, Long userId) {
        // 处理点赞表逻辑
        handleLike(articleId, userId, (short) 1, updateStatus); // likeType=1 表示文章点赞
    }

    /**
     * 通用点赞处理（新增或取消点赞）
     */
    private void handleLike(Long targetId, Long userId, Short likeType, Short updateStatus) {
        // 检查用户是否已点赞（status=1为有效）
        Long likeId = commentsMapper.existsByUserAndTarget(userId, targetId, likeType);

        if (updateStatus == 0) { // 点赞（新增记录）
            if (likeId == null) { // 未点赞过，插入新记录
                Likes likes = new Likes();
                likes.setUserId(userId);
                likes.setTargetId(targetId);
                likes.setLikeType(likeType);
                likes.setStatus((short) 1); // 有效状态

                // 若是文章点赞，设置articleId（评论点赞时articleId为null）
                if (likeType == 1) {
                    likes.setArticleId(targetId); // 文章点赞时，targetId=articleId
                }

                int result = commentsMapper.insertLikes(likes);
                if (result != 1) {
                    throw new RuntimeException("点赞记录新增失败");
                }
            } else {
                throw new RuntimeException("已点赞，不能重复操作");
            }

            // 更新点赞计数（+1）
            int delta = 1;
            updateLikeCount(targetId, likeType, delta);

        } else { // 取消点赞（updateStatus=1）
            if (likeId != null) { // 存在有效点赞记录，取消
                int result = commentsMapper.cancelLike(likeId);
                if (result != 1) {
                    throw new RuntimeException("取消点赞失败");
                }
            } else {
                throw new RuntimeException("未点赞，无法取消");
            }

            // 更新点赞计数（-1）
            int delta = -1;
            updateLikeCount(targetId, likeType, delta);
        }
    }

    /**
     * 更新点赞计数（评论或文章）
     */
    private void updateLikeCount(Long targetId, Short likeType, int delta) {
        if (likeType == 1) { // 文章点赞
            handleArticleLikeCount(targetId, delta);
        } else if (likeType == 2) { // 评论点赞
            handleCommentLikeCount(targetId, delta);
        }
    }

    /**
     * 处理文章点赞计数（复用原有逻辑）
     */
    private void handleArticleLikeCount(Long articleId, int delta) {
        // 原有文章点赞逻辑...
        if (commentsMapper.existsArticleLike(articleId) == null) {
            if (delta == -1) {
                throw new RuntimeException("文章点赞统计不存在，无法减少");
            }
            commentsMapper.insertArticleLike(articleId);
        } else {
            if (delta == -1) {
                int currentCount = commentsMapper.getArticleLikeCount(articleId);
                if (currentCount <= 0) {
                    throw new RuntimeException("文章点赞量不能小于0");
                }
            }
            commentsMapper.updateArticleLike(articleId, delta);
        }
    }

    /**
     * 处理评论点赞计数（复用原有逻辑）
     */
    private void handleCommentLikeCount(Long commentId, int delta) {
        // 原有评论点赞逻辑...
        if (delta == -1) {
            int currentCount = commentsMapper.getCommentLikeCount(commentId);
            if (currentCount <= 0) {
                throw new RuntimeException("点赞量不能小于0");
            }
        }
        commentsMapper.updateCommentLike(commentId, delta);
    }

    @Override
    public Comments createComment(CommentCreateDTO dto) {
        // 1. 校验参数合法性
        validateCommentParams(dto);

        // 2. 构建评论实体
        Comments comment = new Comments();
        comment.setArticleId(dto.getArticleId());
        comment.setUserId(dto.getUserId());
        comment.setParentCommentId(dto.getParentCommentId());
        comment.setContent(dto.getContent());
        comment.setCreateTime(LocalDateTime.now());
        comment.setUpdateTime(LocalDateTime.now());
        comment.setLikeCount(0); // 初始点赞量为0
        comment.setStatus((short) 1); // 默认正常状态

        // 3. 插入评论
        commentsMapper.insertComment(comment);

        // 4. 返回带ID的评论对象
        return comment;
    }

    private void validateCommentParams(CommentCreateDTO dto) {
        if (dto.getArticleId() == null || dto.getArticleId() <= 0) {
            throw new IllegalArgumentException("文章ID不能为空");
        }
        if (dto.getUserId() == null || dto.getUserId() <= 0) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        if (StringUtils.isBlank(dto.getContent())) {
            throw new IllegalArgumentException("评论内容不能为空");
        }
    }

    @Override
    public List<CommentVO> getCommentsByArticleId(Long articleId) {
        // 1. 查询文章下的所有评论
        List<Comments> commentList = commentsMapper.selectByArticleId(articleId);

        // 2. 转换为VO并关联用户信息
        List<CommentVO> voList = commentList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        // 3. 构建嵌套结构（父子关系）
        return buildCommentTree(voList);
    }

    /**
     * 转换评论实体为VO，并关联用户信息
     */
    private CommentVO convertToVO(Comments comment) {
        CommentVO vo = new CommentVO();
        BeanUtils.copyProperties(comment, vo);

        // 查询用户信息
        User user = userMapper.selectById(comment.getUserId());
        if (user != null) {
            vo.setNickname(user.getNickname());
            vo.setUserPic(user.getUserPic());
        }

        return vo;
    }

    /**
     * 构建评论树结构（嵌套父子关系）
     */
    private List<CommentVO> buildCommentTree(List<CommentVO> allComments) {
        // 存储所有评论的映射（key=commentId，value=CommentVO）
        Map<Long, CommentVO> commentMap = new HashMap<>();

        // 顶级评论列表
        List<CommentVO> rootComments = new ArrayList<>();

        // 1. 初始化映射表
        for (CommentVO comment : allComments) {
            commentMap.put(comment.getCommentId(), comment);
        }

        // 2. 构建树结构
        for (CommentVO comment : allComments) {
            if (comment.getParentCommentId() == null) {
                // 顶级评论
                rootComments.add(comment);
            } else {
                // 子评论：找到父评论并添加到其子列表
                CommentVO parent = commentMap.get(comment.getParentCommentId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(comment);
                }
            }
        }

        // 3. 对子评论进行排序（按创建时间升序）
        sortCommentsRecursively(rootComments);

        return rootComments;
    }

    /**
     * 递归排序评论（按创建时间升序）
     */

    private void sortCommentsRecursively(List<CommentVO> comments) {
        if (comments == null || comments.isEmpty()) {
            return;
        }

        // 按创建时间升序排序
        comments.sort(Comparator.comparing(CommentVO::getCreateTime));

        // 递归处理子评论
        for (CommentVO comment : comments) {
            sortCommentsRecursively(comment.getChildren());
        }
    }

    @Override
    public void deleteComment(Long commentId) {
        // 1. 查询评论信息
        Comments comment = commentsMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在: " + commentId);
        }

        // 2. 检查是否已删除
        if (comment.getStatus() == 0) {
            throw new RuntimeException("评论已处于删除状态: " + commentId);
        }

        // 3. 递归删除所有后代评论（包括直接子评论和嵌套子评论）
//        cascadeDeleteChildren(commentId);

        // 4. 删除当前评论
        commentsMapper.updateStatus(commentId, (short) 0);
    }

    @Override
    public List<LikesVO> getValidLikes(Long targetId, Short likeType) {
        if (targetId == null) {
            throw new IllegalArgumentException("targetId 不能为空");
        }
        return commentsMapper.selectValidLikes(targetId, likeType);
    }

    /**
     * 递归删除所有层级的子评论
     */
    private void cascadeDeleteChildren(Long parentId) {
        // 查询所有直接子评论
        List<Comments> children = commentsMapper.selectByParentId(parentId);

        // 递归处理每个子评论
        for (Comments child : children) {
            // 先递归删除子评论的后代
            cascadeDeleteChildren(child.getCommentId());

            // 再删除当前子评论
            commentsMapper.updateStatus(child.getCommentId(), (short) 0);
        }
    }
    @Override
    public PageInfo<CommentVO> getAllCommentsWithoutHierarchy(int pageNum, int pageSize, String sensitiveWord) {
        // 开启分页
        PageHelper.startPage(pageNum, pageSize);
        List<String> sensitiveWords = new ArrayList<>();
        if (sensitiveWord != null && !sensitiveWord.isEmpty()) {
            sensitiveWords = Arrays.asList(sensitiveWord.split(","));
        }
        // 查询评论
        List<Comments> comments = commentsMapper.selectAllComments(sensitiveWords);
        // 转换为 VO 列表
        List<CommentVO> commentVOs = comments.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        return new PageInfo<>(commentVOs);
    }
    @Override
    public void batchDeleteComments(List<Long> commentIds) {
        if (commentIds == null || commentIds.isEmpty()) {
            return;
        }

        // 批量更新评论状态为删除
        int result = commentsMapper.batchUpdateStatus(commentIds, (short) 0);

        if (result != commentIds.size()) {
            throw new RuntimeException("部分评论删除失败，请检查评论状态或ID是否有效");
        }
    }

}
